﻿#ifndef RTCDEFINE_H
#define RTCDEFINE_H
#include <QString>
#include <QVariant>
#include <qdebug.h>
#include <QDataStream>
#include <QMetaEnum>
#include "engine_types.h"
#include "engine_device_manager.h"

#define  RTCSERVICENAME  "RTCService"


class RTCEngineCommand : public QObject {
    Q_OBJECT

public:
    enum Engine_API {
        Engine_Create = 0,
        Engine_Destroy,
        Engine_GetSDKVersion,
        Engine_SetLogDirPath,
        Engine_GetLogDirPath,
        Engine_SetLogLevel,
        Engine_GetErrorDescription,
        Engine_SetEngineEventListener,
        Engine_GetAudioMixingManager,
        Engine_GetAudioDeviceManager,
        Engine_GetVideoDeviceManager,
        Engine_GetCurrentConnectionStatus,
        Engine_JoinChannel,
        Engine_LeaveChannel,
        Engine_GetOnlineRemoteUsers,
        Engine_GetUserInfo,
        Engine_IsUserOnline,
        Engine_IsInCall,
        Engine_PublishLocalVideoStream,
        Engine_PublishLocalAudioStream,
        Engine_IsLocalVideoStreamPublished,
        Engine_IsScreenSharePublished,
        Engine_IsLocalAudioStreamPublished,
        Engine_MuteLocalVideo,
        Engine_MuteLocalAudio,
        Engine_StartScreenShareByDesktopId,
        Engine_StartScreenShareByWindowId,
        Engine_UpdateScreenShareConfig,
        Engine_StopScreenShare,
        Engine_GetScreenShareSourceInfo,
        Engine_GetCurrentScreenShareSourceId,
        Engine_SubscribeAllRemoteAudioStreams,
        Engine_SubscribeAllRemoteVideoStreams,
        Engine_SubscribeRemoteVideoStream,
        Engine_SetRemoteVideoStreamType,
        Engine_SetRemoteDefaultVideoStreamType,
        Engine_EnableLocalVideo,
        Engine_EnableBeautyFace,
        Engine_EnableVirtualBackground,
        Engine_SetVideoEnhance,
        Engine_SetVideoDenoise,
        Engine_SetAudioDenoise,
        Engine_SetVideoEncoderConfiguration,
        Engine_SetScreenShareEncoderConfiguration,
        Engine_SetLocalViewConfig,
        Engine_SetRemoteViewConfig,
        Engine_UpdateViewConfig,
        Engine_StartPreview,
        Engine_StopPreview,
        Engine_RegisterVideoFrameObserver,
        Engine_EnableVideoFrameObserver,
        Engine_SetAudioProfile,
        Engine_EnableAudioVolumeIndication,
        Engine_RegisterAudioFrameObserver,
        Engine_EnableAudioFrameObserver,
        Engine_SetExternalAudioSource,
        Engine_PushExternalAudioFrame,
        Engine_SetExternalAudioRender,
        Engine_PushExternalAudioRenderFrame,
        Engine_EnableCustomAudioCapture,
        Engine_SendCustomAudioCaptureFrame,
        Engine_EnableCustomAudioRender,
        Engine_GetCustomAudioRenderFrame,
        Engine_SetPlayoutSignalVolume,
        Engine_GetPlayoutSignalVolume,
        Engine_SetExternalVideoSource,
        Engine_PushExternalVideoFrame,
        Engine_StartRecord,
        Engine_UpdateRecordLayout,
        Engine_PauseRecord,
        Engine_ResumeRecord,
        Engine_StopRecord,
        Engine_SnapshotVideo,
        Engine_SendMediaExtensionMsg,

        // RtcEngineVideoDeviceManager 接口
        VideoDM_GetCameraList,
        VideoDM_GetCurrentCameraName,
        VideoDM_GetCurrentCameraID,
        VideoDM_SetCurrentCameraName,
        VideoDM_SetCurrentCameraID,
        VideoDM_IsCameraOn,
        VideoDM_SwitchCamera,
        VideoDM_SetCameraZoom,
        VideoDM_SetCameraFlash,
        VideoDM_IsCameraFocusPointSupported,
        VideoDM_SetCameraFocusPoint,
        VideoDM_IsCameraExposurePointSupported,
        VideoDM_SetCameraExposurePoint,
        VideoDM_SetDeviceOrientationMode,

        // RtcEngineAudioDeviceManager 接口
        AudioDM_GetRecordingDeviceList,
        AudioDM_GetCurrentRecordingDeviceId,
        AudioDM_SetCurrentRecordingDeviceId,
        AudioDM_GetPlayoutDeviceList,
        AudioDM_GetCurrentPlayoutDeviceId,
        AudioDM_SetCurrentPlayoutDeviceId,
        AudioDM_SetRecordingDeviceVolume,
        AudioDM_GetRecordingDeviceVolume,
        AudioDM_SetPlayoutDeviceVolume,
        AudioDM_GetPlayoutDeviceVolume,
        AudioDM_SetRecordingDeviceMute,
        AudioDM_SetRecordingDataMute,
        AudioDM_GetRecordingDeviceMute,
        AudioDM_SetPlayoutDeviceMute,
        AudioDM_GetPlayoutDeviceMute,
        AudioDM_StartRecordingDeviceTest,
        AudioDM_StopRecordingDeviceTest,
        AudioDM_StartPlayoutDeviceTest,
        AudioDM_StopPlayoutDeviceTest,
        AudioDM_EnableAudioLevelObserver,
        AudioDM_EnableSystemAudio,
        AudioDM_DisableSystemAudio,
        AudioDM_StartAudioPlayer,
        AudioDM_StartAudioCapture,
        Enable_AI_Denoise,
        //DingRtcEngineAudioMixingManager
        // 错误
        Engine_Invalid
    };

    Q_ENUM(Engine_API)

    static QString commandToString(Engine_API command) {
        const QMetaObject *metaObject = &staticMetaObject;
        QMetaEnum metaEnum = metaObject->enumerator(metaObject->enumeratorOffset());
        return metaEnum.valueToKey(command);
    }
};

class AliRtcEvents : public QObject {
    Q_OBJECT

public:
    enum AliRtcCallbackEvent {
        AliRtcEventJoinChannelResult,
        AliRtcEventLeaveChannelResult,
        AliRtcEventChannelRemainingTimeNotify,
        AliRtcEventRemoteUserOnLineNotify,
        AliRtcEventRemoteUserOffLineNotify,
        AliRtcEventBye,
        AliRtcEventConnectionStatusChanged,
        AliRtcEventNetworkQualityChanged,
        AliRtcEventStatisticsLog,
        AliRtcEventOccurWarning,
        AliRtcEventOccurError,
        AliRtcEventStatisticsLevelLog,
        AliRtcEventQualityReport,
        AliRtcEventLocalAudioStats,
        AliRtcEventLocalVideoStats,
        AliRtcEventRemoteAudioStats,
        AliRtcEventRemoteVideoStats,
        AliRtcEventStats,
        AliRtcEventAudioPublishStateChanged,
        AliRtcEventVideoPublishStateChanged,
        AliRtcEventScreenSharePublishStateChanged,
        AliRtcEventRemoteTrackAvailableNotify,
        AliRtcEventUserAudioMuted,
        AliRtcEventUserVideoMuted,
        AliRtcEventUserVideoEnabled,
        AliRtcEventUserWillResignActive,
        AliRtcEventUserWillBecomeActive,
        AliRtcEventFirstRemoteVideoFrameDrawn,
        AliRtcEventFirstLocalVideoFrameDrawn,
        AliRtcEventFirstVideoPacketSend,
        AliRtcEventFirstVideoPacketReceived,
        AliRtcEventFirstVideoFrameReceived,
        AliRtcEventFirstAudioPacketSend,
        AliRtcEventFirstAudioPacketReceived,
        AliRtcEventRenderRemoteVideoSizeChanged,
        AliRtcEventRenderLocalVideoSizeChanged,
        AliRtcEventAudioSubscribeStateChanged,
        AliRtcEventVideoSubscribeStateChanged,
        AliRtcEventScreenShareSubscribeStateChanged,
        AliRtcEventSubscribeStreamTypeChanged,
        AliRtcEventRecordingDeviceAudioLevel,
        AliRtcEventPlayoutDeviceAudioLevel,
        AliRtcEventAudioVolumeIndication,
        AliRtcEventAudioDeviceStateChanged,
        AliRtcEventVideoDeviceStateChanged,
        AliRtcEventApiCalledExecuted,
        AliRtcEventSnapshotComplete,
        AliRtcEventMediaExtensionMsgReceived,
        AliRtcEventAudioMixingStateChanged,
        AliRtcEventListAllAudioGroups,
        AliRtcEventAudioGroupJoinResult,
        AliRtcEventAudioGroupLeaveResult,
        AliRtcEventAudioGroupDismissResult,
        AliRtcEventAudioGroupMixResult,
        AliRtcEventAudioGroupMemberUpdate,
        AliRtcEventAudioGroupHallMembers,
        AliRtcEventAudioGroupListUpdate
    };

    Q_ENUMS(AliRtcCallbackEvent)

    AliRtcEvents(QObject *parent = nullptr) : QObject(parent) {}

    static QString getEventName(int eventIndex) {
        const QMetaObject *metaObject = &staticMetaObject;
        QMetaEnum metaEnum = metaObject->enumerator(metaObject->enumeratorOffset());
        return metaEnum.valueToKey(eventIndex);
    }
};


#pragma pack(push, 1)

struct RTCEngineRequest {
    RTCEngineCommand::Engine_API command;
    QVector<QVariant> parameters;

    RTCEngineRequest(RTCEngineCommand::Engine_API cmd, const QVector<QVariant>& params)
        : command(cmd), parameters(params) {}

    RTCEngineRequest(){}
};


struct RTCEngineResponse {
    RTCEngineCommand::Engine_API command;
    QVector<QVariant> results; // 使用 QVector 来存储可能多个的返回值
    QString errorMessage;

    RTCEngineResponse(RTCEngineCommand::Engine_API cmd, const QVector<QVariant>& res, const QString& errMsg)
        : command(cmd), results(res), errorMessage(errMsg) {}

    RTCEngineResponse()
        : command(static_cast<RTCEngineCommand::Engine_API>(-1)) // 假设 -1 是一个表示无效命令的枚举值
        , results() // QVector 默认构造函数会创建一个空向量
        , errorMessage() // QString 默认构造函数会创建一个空字符串
    {}
    };


struct RTCEngineCallback {
    AliRtcEvents::AliRtcCallbackEvent event;
    QVector<QVariant> results; // 使用 QVector 来存储可能多个的返回值

    RTCEngineCallback(AliRtcEvents::AliRtcCallbackEvent ev, QVector<QVariant>& res)
            : event(ev), results(res) {}

    RTCEngineCallback(){}
};

#pragma pack(pop)


static QDebug operator<<(QDebug debug, const RTCEngineRequest& request) {
    debug << "RTCEngineRequest {"
          << "command=" << int(request.command)
          << ", parameters=[";

    for (int i = 0; i < request.parameters.size(); ++i) {
        debug << request.parameters[i].toString();
        if (i < request.parameters.size() - 1) {
            debug << ", ";
        }
    }

    debug << "]";
    return debug;
}


static QDebug operator<<(QDebug debug, const RTCEngineResponse& response) {
    debug << "RTCEngineResponse {"
          << "\n  command:" << (int)response.command
          << "\n  results: [";

    for (int i = 0; i < response.results.size(); ++i) {
        debug << (i > 0 ? ", " : "") << response.results[i];
    }

    debug << "]"
          << "\n  errorMessage:" << response.errorMessage
          << "\n}";

    return debug;
}

static QDebug operator<<(QDebug debug, const RTCEngineCallback& callback) {
    debug << "RTCEngineCallback {"
          << "\n  command: " << (int)callback.event
          << "\n  results: [";
    for (int i = 0; i < callback.results.size(); ++i) {
        debug << (i > 0 ? ", " : "") << callback.results[i].toString(); // 将 QVariant 转换为字符串输出
    }
    debug << "]"
          << "\n}";
    return debug;
}

#endif // RTCDEFINE_H
